﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsServerSolutions.Common.UI.TaskDialog;
using Microsoft.WindowsServerSolutions.Properties;
using TV4Home.Server.IssueReporting;

namespace TV4Home.Server.Vail.AddIn
{
    public partial class BugReportForm : PropertyForm
    {
        public BugReportForm()
        {
            InitializeComponent();

            // show OK and Cancel button
            this.SetButtonVisiblity(true, true, false);

            // set progress details
            this.ProgressTitle = "Reporting bug...";
            this.ProgressDescription = "Your bug report is being submitted.";
            this.ProgressStyle = ProgressBarStyle.Continuous;
            this.ProgressCancelable = false;

            // remove OK button as accept button for the form,
            // otherwise Commit() would be called if the Enter key is pressed in the description textbox
            this.AcceptButton = null;

            // prepopulate description field with general information
            txtDescription.Text = String.Format("{0}{0}{0}{0}{0}----- General information ----- {0}Add-In Version: {1}{0}Server Version: {2}{0}SKU: {3}{0}MediaPortal TV Server Version: {4}",
                                                Environment.NewLine,
                                                Utils.Misc.AddInVersion,
                                                new Microsoft.WindowsServerSolutions.Common.VersionInfo()["Server"],
                                                Microsoft.WindowsServerSolutions.Common.SkuInfo.Sku,
                                                File.Exists(Utils.CommonPaths.TVServer_SetupTvEXEPath) ? FileVersionInfo.GetVersionInfo(Utils.CommonPaths.TVServer_SetupTvEXEPath).FileVersion : "(not installed)");

            // set cursor to title field
            this.txtTitle.Select();
        }

        protected override void OnOKButtonClicked(EventArgs e)
        {
            this.OnApplyButtonClicked(e);
        }

        protected override void Commit(bool dismissed)
        {
            // create issue object
            WebIssue issue = new WebIssue
            {
                Title = String.Format("[{0}] {1}", rbIssue.Checked ? "BUG" : "FRQ", txtTitle.Text),
                Description = txtDescription.Text,
                WorkItemType = rbIssue.Checked ? "Issue" : "Feature",
                Component = @"TV4Home\Vail Add-In",
                Priority = new[] { "Low", "Medium", "High" }[rbPriorityLow.Checked ? 0 : (rbPriorityMedium.Checked ? 1 : (rbPriorityHigh.Checked ? 2 : 0))]
            };

            // add attachments
            foreach (ListViewItem item in this.lstAttachments.Items)
            {
                if (item.Tag is WebAttachment)
                    issue.AddAttachment((WebAttachment)item.Tag);
            }

            bgwSubmit.RunWorkerAsync(issue);
        }

        private void bgwSubmit_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // operation succeeded
            if (e.Error == null)
            {
                // show the success form
                using (BugReportSubmitSuccessForm successForm = new BugReportSubmitSuccessForm(e.Result as string))
                    successForm.ShowDialog();

                this.FinishProgress();
                this.Close();

                return;
            }

            // an error occurred
            if (e.Error is ArgumentException)
            {
                TaskMessageBox.Show(e.Error.Message,
                                    "Information",
                                    "Please provide additional data",
                                    TaskDialogButtons.Ok,
                                    TaskDialogIcon.Warning);
            }
            else
            {
                TaskMessageBox.Show(e.Error.Message,
                                    "Error",
                                    "An error occurred while submitting the bug report",
                                    TaskDialogButtons.Ok,
                                    TaskDialogIcon.Error);
            }

            this.FinishProgress();
        }

        private void bgwSubmit_DoWork(object sender, DoWorkEventArgs e)
        {
            WebIssue issue = (WebIssue)e.Argument;

            // input validation
            if (String.IsNullOrWhiteSpace(issue.Title) || issue.Title.Length < 9 || issue.Title.Length > 80)
                throw new ArgumentException("Title must be at least 3 characters long and mustn't exceed 80 characters!"); //TODO: localize exception

            if (String.IsNullOrWhiteSpace(issue.Description) || issue.Description.Length < 10 || issue.Description.Length > 1500)
                throw new ArgumentException("Please enter between 10 and 1500 characters for the description!"); //TODO: localize exception

            // submit report
            e.Result = SubmitBugReport(issue);
        }

        private string SubmitBugReport(WebIssue issue)
        {
            IssueReporting.IssueReporting reporter = new IssueReporting.IssueReporting();

            // attach progress changed event handler
            reporter.ProgressChanged += (sender, e) =>
                                            {
                                                int progress = e.ProgressPercentage;

                                                if (progress < 0)
                                                    progress = 0;
                                                else if (progress > 100)
                                                    progress = 100;

                                                this.UpdateProgress(progress, e.UserState as string);
                                            };

            // report the issue
            reporter.UploadIssue(issue);

            return issue.IssueId.ToString();
        }

        private void btnBrowseAttachment_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK != ofdAttachment.ShowDialog())
                return;

            this.txtAttachmentFilePath.Text = this.ofdAttachment.FileName;
        }

        private void btnAddAttachment_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrWhiteSpace(this.txtAttachmentFilePath.Text))
                return;

            FileInfo fInfo = new FileInfo(this.txtAttachmentFilePath.Text);

            if (!fInfo.Exists)
                return;

            // validate file size
            if (fInfo.Length > 350000)
            {
                TaskMessageBox.Show("Please use an attachment smaller than 350kB or compress the attachment.",
                    "Information",
                    "Attachment is too large!",
                    TaskDialogButtons.Ok,
                    TaskDialogIcon.Information);

                return;
            }

            ListViewItem item = new ListViewItem(fInfo.Name);

            item.Tag = new WebAttachment()
                           {
                               AttachmentFilename = fInfo.Name,
                               AttachmentData = Convert.ToBase64String(File.ReadAllBytes(fInfo.FullName)),
                               AttachmentComment = txtAttachmentDescription.Text
                           };

            this.lstAttachments.Items.Add(item);

            // clear fields
            this.txtAttachmentFilePath.Clear();
            this.txtAttachmentDescription.Clear();
        }

        private void btnRemoveAttachment_Click(object sender, EventArgs e)
        {
            if (this.lstAttachments.SelectedItems.Count > 0)
                this.lstAttachments.Items.Remove(this.lstAttachments.SelectedItems[0]);
        }
    }
}
